package com.block.product.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.block.common.annotate.ExceptionLog;
import com.block.common.constant.AppRspCodeConstant;
import com.block.common.exception.BizException;
import com.block.common.model.dto.CountInfoDTO;
import com.block.common.model.dto.UserInfoDTO;
import com.block.common.service.ICountCommonService;
import com.block.common.service.LogFactory;
import com.block.common.util.LocalDateUtil;
import com.block.common.vo.ResponseVo;
import com.block.db.common.vo.BaseUserInfoVo;
import com.block.db.entity.ProductInfo;
import com.block.db.entity.ProductMemberUnion;
import com.block.db.mapper.ProductMemberUnionMapper;
import com.block.product.enums.ProdPriceTypeEnum;
import com.block.product.factory.UnionTypeFactory;
import com.block.product.service.IProductInfoService;
import com.block.product.service.IProductMemberUnionService;
import com.block.product.service.IProductProfitService;
import com.block.product.service.IProductUnionService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;

@Service
public class ProductUnionServiceImpl implements IProductUnionService {

    private static Logger log = LogFactory.getCommLog();

    @Autowired
    IProductMemberUnionService productMemberUnionService;
    @Autowired
    ICountCommonService countCommonService;
    @Autowired
    IProductProfitService productProfitService;
    @Autowired
    IProductInfoService productInfoService;
    @Resource
    ProductMemberUnionMapper productMemberUnionMapper;

    @Override
    @ExceptionLog(key = "#productId", bizName = "联登产品查询", bizType = "unionProd")
    public ResponseVo findProductUnionInfo(Long productId, BaseUserInfoVo userInfoVo, UserInfoDTO userInfoDTO) throws BizException {

        String result = productMemberUnionService.getUnionProductByUserId(userInfoVo.getUid(), productId);
        if (StrUtil.isNotEmpty(result)) {
            // 该用户不需要展示该产品信息
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("productUrl", result);
            return new ResponseVo(AppRspCodeConstant.SUCCESS, jsonObject);
        }

        ProductInfo productInfo = productInfoService.getById(productId);
        if (ObjectUtil.isEmpty(productInfo) || !ObjectUtil.equal(productInfo.getPriceType(), ProdPriceTypeEnum.UNION.getValue())) {
            log.error("【联登产品信息】产品信息错误【productId】{}", productId);
            return new ResponseVo(AppRspCodeConstant.DATA_INFO_NULL);
        }

        // 查询联登记录
        ProductMemberUnion memberUnion = productMemberUnionMapper.getEntryByUserIdAndProductIdLock(userInfoVo.getUid(), productId);
        if (ObjectUtil.isEmpty(memberUnion)) {
            // 进行撞库操作
            // 用户没有点击产品信息，需要请求产品的信息
            ResponseVo responseVo = UnionTypeFactory.getService(productInfo.getFactoryType()).matchUserInfo(productInfo, userInfoVo);
            log.info("【联登产品信息】联登撞库完成【responseVo】{}", JSON.toJSONString(responseVo));

            boolean matchFlag = true;
            memberUnion = new ProductMemberUnion();
            memberUnion.setProductId(productInfo.getId());
            memberUnion.setUserId(userInfoVo.getUid());
            if (!AppRspCodeConstant.SUCCESS.equals(responseVo.getRspCode())) {
                // 撞库失败，保存失败记录
                memberUnion.setStatus("FAILED");
                matchFlag = false;
            } else {
                // 撞库成功，展示用户信息
                memberUnion.setStatus("INIT");
            }
            memberUnion.setMatchResult(responseVo.getRspMsg());
            boolean save = productMemberUnionService.save(memberUnion);
            log.info("【联登产品信息】保存撞库记录信息【save】{}【matchFlag】{}", save, matchFlag);
            if (!matchFlag) {
                return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION);
            }
        }

        // 没有记录的时候，才进行联登
        return this.unionLoginRegisterUser(productInfo, userInfoVo, memberUnion, userInfoDTO);

    }

    /**
     * 联登注册用户信息
     */
    @Override
    public ResponseVo unionLoginRegisterUser(ProductInfo productInfo, BaseUserInfoVo userInfoVo, ProductMemberUnion memberUnion, UserInfoDTO userInfoDTO) throws BizException {

        // 撞库成功，进行用户注册，获取产品详情
        ResponseVo responseVo = UnionTypeFactory.getService(productInfo.getFactoryType()).registerUserInfo(productInfo, userInfoVo);
        log.info("【联登产品信息】联登注册完成【responseVo】{}", JSON.toJSONString(responseVo));

        ProductMemberUnion updateEntity = new ProductMemberUnion();
        updateEntity.setId(memberUnion.getId());
        updateEntity.setType(memberUnion.getType());
        updateEntity.setRegisterResult(responseVo.getRspMsg());

        if (!AppRspCodeConstant.SUCCESS.equals(responseVo.getRspCode())) {
            // 注册用户信息失败
            updateEntity.setStatus("ERROR");
            boolean updateRes = productMemberUnionService.updateById(updateEntity);
            log.info("【联登产品信息】联登失败，保存信息【updateRes】{}【responseVo】{}", updateRes, JSON.toJSONString(responseVo));
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION);
        }

        // 统计收益信息
        // 联登成功之后
        saveCountInfo(userInfoVo, productInfo, userInfoDTO);

        // 保存联登产品信息
        JSONObject resultData = responseVo.getData();
        String productUrl = resultData.getString("productUrl");

        updateEntity.setProductId(memberUnion.getProductId());
        updateEntity.setUserId(memberUnion.getUserId());
        updateEntity.setProductUrl(productUrl);
        updateEntity.setStatus("SUCCESS");
        LocalDateTime nowDate = LocalDateUtil.getNowAddHours(productInfo.getUnionShowHours());// 联登成功，增加一天的展示时间
        updateEntity.setShowDate(nowDate);

        // 保存产品用户信息
        boolean saveRes = productMemberUnionService.updateInfo(updateEntity);
        log.info("【联登产品信息】保存用户联登记录【uid】{}【uid】{}【productId】{}【productUrl】{}", saveRes, userInfoVo.getUid(), productInfo.getId(), productUrl);

        // 进行产品信息的保护
        return new ResponseVo(AppRspCodeConstant.SUCCESS, resultData);
    }


    /**
     * 记录联登 统计信息
     */
    private void saveCountInfo(BaseUserInfoVo userInfoVo, ProductInfo productInfo, UserInfoDTO userInfoDTO) {

        try {

            // 下游产品 联登已经产生收益，记录结果
            CountInfoDTO countInfoDTO = new CountInfoDTO();
            countInfoDTO.setChannelCode(userInfoVo.getChannelCode());
            countInfoDTO.setProUnionCount(1);
            countInfoDTO.setProUnionProfit(productInfo.getPriceAmount());
            countCommonService.calculateDataInfo2(countInfoDTO);

            // todo 统计产品联登 收益
//            productProfitService.saveProductProfit(productInfo.getId(), userInfoDTO);

            // 更新收益信息

        } catch (Exception exception) {
            exception.printStackTrace();
            // TODO: 2022/8/30 邮件通知
        }
    }


}
